<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns="http://www.w3.org/2000/svg"
	xmlns:svg="http://www.w3.org/2000/svg"
	xmlns:html="http://www.w3.org/1999/xhtml"
	xmlns:doc="livcos.org/ns/doc"
	xmlns:dg="livcos.org/ns/doc/diagram"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:f="livcos.org/ns/xslt/function"
	exclude-result-prefixes="doc html dg f xs svg xlink">

	<xsl:import href="base.xsl"/>
	
	<xsl:variable name="tmpl_path"
		select="'/livcos.org/type/template/livcos.org/ns/doc/diagram/path#template_1'"/>
	<xsl:variable name="tmpl_line"
		select="'/livcos.org/type/template/livcos.org/ns/doc/diagram/line#template_1'"/>
	
	<xsl:template match="dg:*" mode="connect">
		<xsl:copy-of select="."/>
	</xsl:template>
	
	<xsl:template match="dg:connect" mode="connect">
		<xsl:variable name="sB" select="../*[@id = current()/@start]"/>
		<xsl:variable name="eB" select="../*[@id = current()/@end]"/>
		<xsl:variable name="s1" select="f:hullV($sB, f:centerV($eB))"/>
		<xsl:variable name="e1" select="f:hullV($eB, $s1)"/>
		<xsl:variable name="e2" select="f:hullV($eB, f:centerV($sB))"/>
		<xsl:variable name="s2" select="f:hullV($sB, $e2)"/>
		<xsl:variable name="e" select="f:hullV($eB, f:mulV(f:addV($s1, $s2), 0.5))"/>
		<xsl:variable name="s" select="f:hullV($sB, f:mulV(f:addV($e1, $e2), 0.5))"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:copy-of select="*"/>
			<xsl:variable name="p" select="f:printV(f:mulV(f:addV($s, $e), 0.5))"/>
			<dg:line to="{$p}" tmpl="{$tmpl_path}" tmpl-args="{concat(@ref, ':', $p)}"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:connect[@start = @end]" mode="connect">
		<xsl:variable name="b" select="../*[@id = current()/@start]"/>
		<xsl:variable name="s0" select="f:hullV($b, f:addV(f:centerV($b), (0, 10000000)))"/>
		<xsl:variable name="num"
			select="count(preceding-sibling::dg:connect[(@start = current()/@start) and (@start = @end)])"/>
		<xsl:variable name="s" select="f:addV($s0, ($num * 20, 0))"/>
		<xsl:variable name="p1" select="f:addV($s, (0, 10))"/>
		<xsl:variable name="p2" select="f:addV($s, (15, 10))"/>
		<xsl:variable name="e" select="f:hullV($b, $p2)"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:attribute name="viewPortMaxX"><xsl:value-of select="$p2[1]"/></xsl:attribute>
			<xsl:attribute name="viewPortMaxY"><xsl:value-of select="$p2[2]"/></xsl:attribute>
			<xsl:copy-of select="*"/>
			<xsl:variable name="tmpl-args" select="concat(@ref, ':', f:printV($p1), ':', f:printV($p2))"/>
			<dg:line tmpl="{$tmpl_path}" tmpl-args="{$tmpl-args}" to="{f:printV($p1)}"/>
			<dg:line tmpl="{$tmpl_path}" tmpl-args="{$tmpl-args}" to="{f:printV($p2)}"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:connect[@path]" mode="connect" priority="2">
		<xsl:variable name="sB" select="../*[@id = current()/@start]"/>
		<xsl:variable name="eB" select="../*[@id = current()/@end]"/>
		<xsl:variable name="ps" select="tokenize(@path, ' ')"/>
		<xsl:variable name="s" select="f:hullV($sB, f:castV($ps[1]))"/>
		<xsl:variable name="e" select="f:hullV($eB, f:castV($ps[last()]))"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:copy-of select="*"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:connect[dg:*/@to]" mode="connect" priority="2">
		<xsl:variable name="sB" select="../*[@id = current()/@start]"/>
		<xsl:variable name="eB" select="../*[@id = current()/@end]"/>
		<xsl:variable name="s" select="f:hullV($sB, f:castV((dg:*/@to)[1]))"/>
		<xsl:variable name="e" select="f:hullV($eB, f:castV((dg:*/@to)[last()]))"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:apply-templates select="*" mode="#current">
				<xsl:with-param name="startV" select="$s"/>
				<xsl:with-param name="endV" select="$e"/>
			</xsl:apply-templates>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:line" mode="connect">
		<xsl:param name="startV"/>
		<xsl:param name="endV"/>
		<xsl:variable name="t" select="f:castV(@to)"/>
		<xsl:if test="position() = 1">
			<xsl:variable name="p" select="f:printV(f:mulV(f:addV($startV, $t), 0.5))"/>
			<dg:line to="{$p}" tmpl="{$tmpl_line}" tmpl-args="{$p}"/>
		</xsl:if>
		<xsl:copy-of select="."/>
		<xsl:variable name="next" select="following-sibling::dg:line[1]"/>
		<xsl:variable name="e" select="if ($next) then f:castV($next/@to) else $endV"/>
		<xsl:variable name="p" select="f:printV(f:mulV(f:addV($t, $e), 0.5))"/>
		<dg:line to="{$p}" tmpl="{$tmpl_line}" tmpl-args="{$p}"/>
	</xsl:template>
	
	<xsl:function name="f:centerV" as="xs:double*">
		<xsl:param name="box" as="element()"/>
		<xsl:apply-templates select="$box" mode="centerV"/>
	</xsl:function>
	
	<xsl:function name="f:hullV" as="xs:double*">
		<xsl:param name="box" as="element()"/>
		<xsl:param name="p" as="xs:double*"/>
		<xsl:apply-templates select="$box" mode="hullV">
			<xsl:with-param name="p" select="$p"/>
		</xsl:apply-templates>
	</xsl:function>
	
	<xsl:template match="dg:box" mode="centerV" as="xs:double*">
		<xsl:copy-of select="f:castV(@pos)"/>
	</xsl:template>
	
	<xsl:template match="dg:box" mode="hullV" as="xs:double*">
		<xsl:param name="p"/>
		<xsl:variable name="w" select="@width div 2"/>
		<xsl:variable name="h" select="@height div 2"/>
		<xsl:variable name="c" select="f:castV(@pos)"/>
		<xsl:variable name="a" select="f:rotateV(f:subV($p, $c), -@angle)"/>
		<xsl:variable name="r" as="xs:double*">
			<xsl:value-of select="if (abs($a[1]) > $w) then $w * abs($a[1]) div $a[1] else $a[1]"/>
			<xsl:value-of select="if (abs($a[2]) > $h) then $h * abs($a[2]) div $a[2] else $a[2]"/>
		</xsl:variable>
		<xsl:copy-of select="f:addV($c, f:rotateV($r, @angle))"/>
	</xsl:template>
	
	<xsl:template match="dg:circle" mode="centerV" as="xs:double*">
		<xsl:copy-of select="f:castV(@pos)"/>
	</xsl:template>
	
	<xsl:template match="dg:circle" mode="hullV" as="xs:double*">
		<xsl:param name="p"/>
		<xsl:variable name="c" select="f:castV(@pos)"/>
		<xsl:variable name="a" select="f:subV($p, $c)"/>
		<xsl:variable name="r" select="@radius div f:lenV($a)"/>
		<xsl:copy-of select="$c[1] + $a[1] * $r, $c[2] + $a[2] * $r"/>
	</xsl:template>
	
</xsl:stylesheet>